﻿// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using Utf8Json;

namespace SnapObjects.Data
{
    internal class UTF8JsonProvider : IJsonProvider
    {
        public INodeReader GetNodeReader(string raw)
        {
            return UTF8JNodeReader.Parse(raw);
        }

        public INodeWriter GetNodeWriter()
        {
            return new UTF8JNodeWriter();
        }

        public string SerializeObject(object value)
        {
            if (value == null)
            {
                return "null";
            }

            Type type = value.GetType();

            if (type.IsPublic || type.IsNestedPublic)
            {
                return JsonSerializer.ToJsonString(value);
            }

            return JsonSerializer.ToJsonString(value, Utf8Json.Resolvers.StandardResolver.AllowPrivate);
        }

        public T DeserializeObject<T>(string value)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            else if (String.IsNullOrWhiteSpace(value))
            {
                return default;
            }

            Type type = typeof(T);

            if (type.IsPublic || type.IsNestedPublic)
            {
                return JsonSerializer.Deserialize<T>(value);
            }

            return JsonSerializer.Deserialize<T>(value, Utf8Json.Resolvers.StandardResolver.AllowPrivate);
        }

        public object DeserializeObject(string value, Type type)
        {
            if (value == null)
            {
                throw new ArgumentNullException(nameof(value));
            }
            else if (String.IsNullOrWhiteSpace(value))
            {
                return default;
            }

            if (type == null)
            {
                throw new ArgumentNullException(nameof(type));
            }

            if (type.IsPublic || type.IsNestedPublic)
            {
                return JsonSerializer.NonGeneric.Deserialize(type, value);
            }

            return JsonSerializer.NonGeneric.Deserialize(
                type, value, Utf8Json.Resolvers.StandardResolver.AllowPrivate);
        }
    }
}
